/**
 * Copyright 2020-2030 Jinhui Technology Co. LTD  All Rights Reserved.
 */
package jgl.vajra.operator.netty;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;

import java.util.List;

import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import jgl.vajra.operator.event.GrabOrderEvent;
import jgl.vajra.operator.event.GrabOrderLoginStateEvent;
import jgl.vajra.operator.event.GrabOrderModifyEvent;
import jgl.vajra.operator.event.OrderDelayEvent;
import jgl.vajra.operator.event.OrderDetailsCancelEvent;
import jgl.vajra.operator.event.OrderPageListEvent;
import jgl.vajra.operator.event.PushDanmuInfoEvent;
import jgl.vajra.operator.event.PushMachineOrderEvent;
import jgl.vajra.operator.manager.AccountManager;
import jgl.vajra.operator.manager.SocketPushManager;
import jgl.vajra.operator.manager.VoiceManager;
import jgl.vajra.operator.netty.gson.IntegerNullAdapter;
import jgl.vajra.operator.netty.gson.LongNullAdapter;
import jgl.vajra.operator.netty.gson.StringNullAdapter;
import jgl.vajra.operator.widget.manager.SPManager;
import jgl.vajra.operator.widget.retrofithelper.utils.AEACCoder;
import jgl.vajra.operator.widget.utils.PhoneUtils;
import jgl.vajra.operator.widget.utils.UIUtils;

/**
 * . <br>
 *
 * @author nongkegai<br>
 * @version <br>
 * @date Create in 2021/11/5 16:56 <br>
 * @description 1.0 <br>
 */

public class ClientHandler extends ChannelInboundHandlerAdapter {

    private final PooledByteBufAllocator allocator = new PooledByteBufAllocator(false);

    public static final Gson gson = new GsonBuilder()
            .registerTypeAdapter(String.class, new StringNullAdapter())
            .registerTypeAdapter(Integer.class, new IntegerNullAdapter())
            .registerTypeAdapter(Long.class, new LongNullAdapter()).create();

    private AEACCoder aesCCoderUtil = new AEACCoder();

    private ImConnection imConnection = new ImConnection();

    public static boolean isLogin = false;
    private MessageInfo userInfo;

    public static Channel channel;


    public static Channel getChannel() {
        return channel;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        try {
            System.out.println("出错了: " + cause.toString());
        } catch (Exception e) {
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            String eventType = null;
            switch (event.state()) {
                case READER_IDLE:
                    //重新连接
                    //onConnect(ctx);
                    System.out.println("长期没收到服务器推送数据");
                    //打印报错
                   /* Looper.prepare();
                    ToastUtils.showShort("长期没收到服务器推送数据");
                    Looper.loop();*/
                    isLogin = false;
                    break;
                case WRITER_IDLE:
                    //发送心跳包
                    System.out.println("发送心跳包");
                    if (ctx.channel().isActive() && ctx.channel().isWritable()) {
                        MessageInfo userInfo = new MessageInfo();
                        userInfo.type = 2;
                        userInfo.invitation = AccountManager.getInstance().getLoginData(UIUtils.getContext()).invitation;
                        userInfo.udid = PhoneUtils.getUDID();
                        System.out.println("userInfo.invitation发送心跳包==" + userInfo.invitation);
                        String jsonStr = gson.toJson(userInfo);
                        ctx.writeAndFlush(jsonStr);
                    }
                    break;
                case ALL_IDLE:
                    eventType = "读写空闲";
                    break;
            }
            //System.out.println(ctx.channel().remoteAddress() + "超时事件" + eventType);
            //ctx.channel().close();
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        /*List<MessageInfo> messageInfoList = JSONArray.parseArray(msg.toString(), MessageInfo.class);*/
//        MessageInfo messageInfo = JSONObject.parseObject(msg.toString(), MessageInfo.class);

        String messageStr = (String) msg;
        System.out.println("您好222...." + messageStr);
        MessageInfo messageInfo = gson.fromJson(messageStr, MessageInfo.class);
        int msgType = messageInfo.type;
        int status = messageInfo.status;
        System.out.println(msgType + "您好333....");
        if (SPManager.MineData.getVoicePlayback() && !TextUtils.isEmpty(messageInfo.voice)) {

            if (msgType == 3 || msgType == 7) {//收到客户端下的订单
                VoiceManager.getInstance().voicePlayback(messageInfo.voice);
            } else if (getIsOrderExistence(String.valueOf(messageInfo.content.orderId))) {
                VoiceManager.getInstance().voicePlayback(messageInfo.voice);
            }
        }

        if (isLogin && msgType > 2 && msgType < 20)//判断是否登录成功 2是心跳包
            if (msgType == 3) {
                MessageInfo message = new MessageInfo();
                message.type = messageInfo.type;
                message.userType = messageInfo.userType;
                message.status = messageInfo.status;
                message.invitation = messageInfo.invitation;
                message.udid = messageInfo.udid;
                message.token = messageInfo.token;
                message.description = messageInfo.description;
                message.voice = messageInfo.voice;
                message.content = messageInfo.content;
                message.carList = messageInfo.carList;
                SocketPushManager.getInstance().pushReceiveMessage(gson.toJson(message), ctx.channel());//确定收到信息
            } else {
                SocketPushManager.getInstance().pushReceiveMessage(messageStr, ctx.channel());//确定收到信息
            }


        try {
            // int msgType = userInfo.type;
            if (msgType == 1) {
                if (status == 1) {
                    this.isLogin = true;
                    channel = ctx.channel();
                    EventBus.getDefault().post(new GrabOrderLoginStateEvent(true));

                    SPManager.HomeData.saveSocketHeartbeatLastTime(System.currentTimeMillis());

                    System.out.println("ok.....");
                } else {
                    onConnect(ctx);
                    System.out.println("登录失败");
                }
//                System.out.println("收到登录信息: "+userInfo.invitation);
            } else if (msgType == 2) {
                isLogin = true;
                channel = ctx.channel();
                SPManager.HomeData.saveSocketHeartbeatLastTime(System.currentTimeMillis());

                System.out.println("收到服务端回写的心跳包" + channel.isActive() + channel.isWritable());
            } else if (msgType == 3) {//收到客户端下的订单(需要抢)
                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().post(new GrabOrderEvent(content, messageInfo.carList, messageInfo.order, messageInfo.udid));

                System.out.println("收到订单信息3: " + content);
             /*   MessageOrderBean beanMessage = JSONObject.parseObject(messageStr, MessageOrderBean.class);
                System.out.println("收到订单信息: " + beanMessage.toString());
                System.out.println("收到订单信息2: " + beanMessage.addressData.get(0).address);*/
            } else if (msgType == 4) {//收到机主抢到的订单(不需要抢)
                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().post(new PushMachineOrderEvent(content));

                //刷新订单列表
                EventBus.getDefault().postSticky(new OrderPageListEvent());

                System.out.println("收到订单信息4: " + content);
            } else if (msgType == 5) {//客户端打赏
                String content = gson.toJson(messageInfo.content);
                EventBus.getDefault().postSticky(new GrabOrderModifyEvent(content));
                System.out.println("收到订单信息5: ");
            } else if (msgType == 6) {//客户端取消订单
                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().postSticky(new OrderDetailsCancelEvent(content));

                //刷新订单列表
                EventBus.getDefault().postSticky(new OrderPageListEvent());

                System.out.println("收到订单信息6: ");

            } else if (msgType == 7) {//客户端更换司机

                //车主或者师傅取消订单
                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().postSticky(new OrderDetailsCancelEvent(content));

                //刷新订单列表
                EventBus.getDefault().postSticky(new OrderPageListEvent());

                System.out.println("收到订单信息7: ");
            }else if(msgType == 12){//订单延时

                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().postSticky(new OrderDelayEvent(content));

                //刷新订单列表
                EventBus.getDefault().postSticky(new OrderPageListEvent());
            } else if (msgType == 30) {//客户端评论完,弹幕显示
                System.out.println("收到订单信息30: ");
                MessageBody messageBody = messageInfo.content;
                String content = gson.toJson(messageBody);
                EventBus.getDefault().postSticky(new PushDanmuInfoEvent(content));

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    //订单是否存在
    private boolean getIsOrderExistence(String orderId) {

        List<GrabOrderBean> orderListInfo = SPManager.HomeData.getOrderListInfo();
        if (orderListInfo.size() != 0) {
            for (int i = 0; i < orderListInfo.size(); i++) {
                Logger.d(orderId + "订单号" + orderListInfo.get(i).orderId);
                if (orderListInfo.get(i).orderId.equals(orderId)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("掉线了...");

        channel = null;
        //使用过程中断线重连
        super.channelInactive(ctx);
        onConnect(ctx);
        EventBus.getDefault().post(new GrabOrderLoginStateEvent(false));

    }

    public void onConnect(ChannelHandlerContext ctx) {
        this.isLogin = false;
        try {
            ctx.channel().disconnect();
        } catch (Exception e) {
        }
        try {
            ctx.channel().close();
        } catch (Exception e) {
        }
        try {
            //从EventLoop中注销掉channel
            if (ctx.channel().pipeline().get("ping") != null)
                ctx.pipeline().remove("ping");
            if (ctx.channel().pipeline().get("encoder") != null)
                ctx.pipeline().remove("encoder");
            if (ctx.channel().pipeline().get("decoder") != null)
                ctx.pipeline().remove("decoder");
            if (ctx.channel().pipeline().get("handler") != null)
                ctx.channel().pipeline().remove("handler");
            ctx.channel().deregister();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        imConnection.connect();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        try {

        } catch (Exception e) {
            System.out.println("连接出错");
        }
    }
}
